package comp.wxapi.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DateUtils {

	/** 锁对象 */
	private static final Object lockObj = new Object();
	/** 存放不同的日期模板格式的sdf的Map */
	private static Map<String, ThreadLocal<SimpleDateFormat>> sdfMap = new HashMap<String, ThreadLocal<SimpleDateFormat>>();

	private static Logger logger = LoggerFactory.getLogger(DateUtils.class);

	public static final String DATE_PATTERN = "yyyy-MM-dd";

	public static final String DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";

	public static final String DATETIME_PATTERN_MILLISECOND = "yyyy-MM-dd HH:mm:ss.SSS";
	
	public static final String ZONE_ID = "UTC+8";

	/**
	 * 返回一个ThreadLocal的sdf,每个线程只会new一次sdf
	 * 
	 * @param pattern
	 * @return
	 */
	private static SimpleDateFormat getSdf(final String pattern) {
		ThreadLocal<SimpleDateFormat> tl = sdfMap.get(pattern);
		// 此处的双重判断和同步是为了防止sdfMap这个单例被多次put重复的sdf
		if (tl == null) {
			synchronized (lockObj) {
				tl = sdfMap.get(pattern);
				if (tl == null) {
					// 只有Map中还没有这个pattern的sdf才会生成新的sdf并放入map
					logger.info("put new sdf of pattern " + pattern + " to map");
					// 这里是关键,使用ThreadLocal<SimpleDateFormat>替代原来直接new SimpleDateFormat
					tl = new ThreadLocal<SimpleDateFormat>() {
						@Override
						protected SimpleDateFormat initialValue() {
							return new SimpleDateFormat(pattern);
						}
					};
					sdfMap.put(pattern, tl);
				}
			}
		}
		return tl.get();
	}

	/**
	 * 时间格式化
	 * 
	 * @param date
	 * @param pattern
	 * @return
	 */
	public static String format(Date date, String pattern) {

		return getSdf(pattern).format(date);
	}

	/**
	 * 时间转字符串，默认yyyy-MM-dd HH:mm:ss格式
	 * 
	 * @param date
	 * @return
	 */
	public static String format(Date date) {

		return format(date, DATETIME_PATTERN);
	}

	/**
	 * 字符串时间转化
	 * 
	 * @param dateStr
	 * @param pattern
	 * @return
	 * @throws ParseException
	 */
	public static Date parse(String dateStr, String pattern) {

		try {
			return getSdf(pattern).parse(dateStr);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 字符串转时间，默认转换的时间格式yyyy-MM-dd HH:mm:ss
	 * 
	 * @param dateStr
	 * @return
	 */
	public static Date parse(String dateStr) {

		return parse(dateStr, DATETIME_PATTERN);
	}
	
	public static Date UTC8DateTime() {
		ZoneId zoneId = ZoneId.of(ZONE_ID);
		LocalDateTime localDateTime = LocalDateTime.now(zoneId);
		return parse(localDateTime.toString(), "yyyy-MM-dd'T'HH:mm:ss");
	}
}
